/*-
 * Copyright (c) 2009 Jonathan Anderson
 * All rights reserved.
 *
 * WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED
 * ON IN PRODUCTION SYSTEMS.  IT WILL BREAK YOUR SOFTWARE IN NEW AND
 * UNEXPECTED WAYS.
 * 
 * This software was developed at the University of Cambridge Computer
 * Laboratory with support from a grant from Google, Inc. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/capability.h>
#include <libuserangel.h>

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>

#include <QtGui>
#include "TextEditor.h"



TextEditor::TextEditor()
	: QMainWindow()
{
	ui.setupUi(this);
	connect(ui.actionOpen,     SIGNAL(activated()), this, SLOT(open()));
	connect(ui.actionSave,     SIGNAL(activated()), this, SLOT(save()));
	connect(ui.actionClose,    SIGNAL(activated()), this, SLOT(close()));
	connect(ui.actionQuit,     SIGNAL(activated()), this, SLOT(quit()));

	show();
}


TextEditor::~TextEditor()
{
	close();
}


void TextEditor::open()
{/*
	QFile *file = QFileDialog::getOpenFile(this, tr("Open File"));
*/
	
	struct ua_powerbox_options options;
	options.ui              = UA_QT;
	options.operation       = UA_OPEN_FILE;
	options.parent_window   = this->winId();
	options.start_path      = "";
	options.pathlen         = 0;
	options.start_fd        = -1;
	options.mult            = false;
	options.filter          = "";
	options.filterlen       = 0;
	options.flags           = O_RDONLY;
	options.rights          = CAP_FSTAT | CAP_SEEK | CAP_FSYNC | CAP_READ;

	int fdcount = 1;
	int fd;
	char *name;

	if(ua_powerbox(&options, &fd, &name, &fdcount))
	{
		if(errno != ECANCELED)
			QMessageBox::critical(this,
			                      tr("Powerbox Error"),
			                      tr("Error opening file chooser: ")
			                       + strerror(errno));
		return;
	}

	QFile *file = new QFile(name, this);

	if(file)
	{
		ui.text->setPlainText(file->readAll());
		file->close();
	}
	else
	{
		switch(errno)
		{
			case ECANCELED:
				// user cancelled dialog; do nothing
				break;

			case EAGAIN:
				QMessageBox::warning(this, tr("File Chooser Problem"),
					tr("Couldn't open file chooser; is your powerbox server running?"));
				break;

			default:
				QMessageBox::critical(this,
			      tr("Error in File Chooser"),
					tr("Error encountered opening file via the file chooser: ")
					    + strerror(errno));
		}
	
		return;
	}
}


void TextEditor::save()
{
	struct ua_powerbox_options options;
	options.ui              = UA_QT;
	options.operation       = UA_SAVE_FILE;
	options.parent_window   = this->winId();
	options.start_path      = "";
	options.pathlen         = 0;
	options.start_fd        = -1;
	options.mult            = false;
	options.filter          = "";
	options.filterlen       = 0;
	options.flags           = O_WRONLY | O_CREAT | O_TRUNC;
	options.rights          = CAP_FSTAT | CAP_SEEK | CAP_FSYNC | CAP_READ | CAP_WRITE | CAP_FTRUNCATE;
	options.umask		= 0666;

	int fdcount = 1;
	int fd;
	char *name;

	if(ua_powerbox(&options, &fd, &name, &fdcount))
	{
		QMessageBox::critical(this,
		                      tr("Powerbox Error"),
		                      tr("Error opening User Angel powerbox: ")
		                       + strerror(errno));
		return;
	}

	QFile file(this);
	file.open(fd, QFile::ReadWrite | QFile::Truncate);
	file.write(ui.text->toPlainText().toAscii());
	file.flush();
}


void TextEditor::close()
{
	ui.text->setPlainText("");
}


void TextEditor::quit()
{
	close();
	QMainWindow::close();
}

